package com.ruoyi.ams.service;


//import com.baomidou.dynamic.datasource.annotation.DS;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ruoyi.ams.domain.AmsOwnUserAssetAuthority;
import com.ruoyi.ams.domain.vo.AssetFullInfoAddVo;

import com.ruoyi.common.core.domain.AsmsAssetFullInfo;
import com.ruoyi.common.core.domain.AssetInfoView;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.*;
import com.ruoyi.common.core.exception.ServiceException;
import com.ruoyi.common.core.token.TokenService;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.page.TableDataInfo;

import com.ruoyi.system.controller.SysDeptController;
import com.ruoyi.system.controller.SysUserController;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.asms.service.IAsmsAssetFullInfoService;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @Description
 * @Author YangJun
 * @Date 2021年10月19日 14:09:01
 **/
@Service
public class AmsReusingService {

    @Autowired
    private IAmsAssetTemplateService amsAssetTemplateService;
    @Autowired
    private IAmsAssetInfoService amsAssetInfoService;
    @Autowired
    private IAmsOwnUserAssetAuthorityService amsOwnUserAssetAuthorityService;

    @Autowired
    private IAmsAssetBrandService amsAssetBrandService;
    @Autowired
    private IAmsOwnAddressService amsOwnAddressService;
    @Autowired
    private IAmsAssetTypeService amsAssetTypeService;
    @Autowired
    private IAmsAssetProjectService projectService;

    @Autowired
    private IAssetInfoViewService assetInfoViewService;
    @Autowired
    private TokenService tokenService;
//    @Autowired
//    private RemoteDeptService remoteDeptService;
//    @Autowired
//    private RemoteUserService remoteUserService;
    @Autowired
    private SysDeptController deptController;
    @Autowired
    private SysUserController userController;
    @Autowired
    private IAsmsAssetFullInfoService assetFullInfoService;

    public AmsAssetTemplate findAmsAssetTemplate(AmsAssetTemplate template) {
        QueryWrapper<AmsAssetTemplate> queryWrapper = new QueryWrapper<>();
        boolean find = false;
        if (template.getAssetTypeId() != null) {
            find = true;
            queryWrapper.eq(AmsAssetTemplate.ASSET_TYPE_ID, template.getAssetTypeId());
        }
        if (StringUtils.isNotEmpty(template.getAssetTemplateName())) {
            find = true;
            queryWrapper.eq(AmsAssetTemplate.ASSET_TEMPLATE_NAME, template.getAssetTemplateName());
        }
        if (StringUtils.isNotEmpty(template.getSpecification())) {
            find = true;
            queryWrapper.eq(AmsAssetTemplate.SPECIFICATION, template.getSpecification());
        }
        if (find) {
            return amsAssetTemplateService.getOne(queryWrapper, false);
        }
        return null;
    }

    public AmsAssetInfo findAmsAssetInfo(AmsAssetInfo amsAssetInfo) {
        QueryWrapper<AmsAssetInfo> queryWrapper = new QueryWrapper<>();

        boolean find = false;
        if (StringUtils.isNotEmpty(amsAssetInfo.getSn())) {
            queryWrapper.eq(AmsAssetInfo.SN, amsAssetInfo.getSn());
            find = true;
        }
        if (StringUtils.isNotEmpty(amsAssetInfo.getAssetCode())) {
            queryWrapper.eq(AmsAssetInfo.ASSET_CODE, amsAssetInfo.getAssetCode());
            find = true;
        }
        if (find) {
            return amsAssetInfoService.getOne(queryWrapper, false);
        }
        return null;

    }

    public AmsOwnUserAssetAuthority tempUserOpenDoorInfo(Long userId, Long assetId) {
        System.out.println();
        List<AmsOwnUserAssetAuthority> list = amsOwnUserAssetAuthorityService.list(new QueryWrapper<AmsOwnUserAssetAuthority>()
                .eq(AmsOwnUserAssetAuthority.USER_ID, userId)
                .eq(AmsOwnUserAssetAuthority.ASSET_ID, assetId).orderByDesc(AmsOwnUserAssetAuthority.CREATE_TIME));
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    public AsmsAssetFullInfo setAssetInfo(AssetFullInfoAddVo assetFullInfoAddVo) {
        AsmsAssetFullInfo assetFullInfo = new AsmsAssetFullInfo();
        BeanUtils.copyProperties(assetFullInfoAddVo, assetFullInfo);
        assetFullInfo.setAssetInfoIsDelete(assetFullInfoAddVo.getIsDelete());
        if (assetFullInfoAddVo.getUseDeptId() != null) {
            R<SysDept> sysDept = deptController.getDeptById(assetFullInfoAddVo.getUseDeptId());
            if (sysDept.getCode() == R.FAIL) {
                throw new ServiceException(sysDept.getMsg());
            }
            assetFullInfo.setUParentId(sysDept.getData().getParentId());
            assetFullInfo.setUAncestors(sysDept.getData().getAncestors());
            assetFullInfo.setUDeptShortName(sysDept.getData().getDeptShortName());
            assetFullInfo.setUDeptFullName(sysDept.getData().getDeptFullName());
            assetFullInfo.setULeader(sysDept.getData().getLeader());
            assetFullInfo.setUEmail(sysDept.getData().getEmail());
            assetFullInfo.setUPhone(sysDept.getData().getPhone());
        }

        if (assetFullInfoAddVo.getUserId() != null) {
            R<SysUser> sysUser = userController.getUserByIdR(assetFullInfoAddVo.getUserId());
            if (sysUser.getCode() == R.FAIL) {
                throw new ServiceException(sysUser.getMsg());
            }
            if (sysUser != null) {
                BeanUtils.copyProperties(sysUser, assetFullInfo);
            }
        }

        AmsAssetBrand assetBrand = amsAssetBrandService.getById(assetFullInfoAddVo.getBrandId());
        if (assetBrand != null) {
            BeanUtils.copyProperties(assetBrand, assetFullInfo);
        }

        AmsOwnAddress ownAddress = amsOwnAddressService.getById(assetFullInfoAddVo.getAddressId());
        if (ownAddress != null) {
            assetFullInfo.setAddressParentId(ownAddress.getParentId());
            assetFullInfo.setAddressId(assetFullInfoAddVo.getAddressId());
            assetFullInfo.setAddressAncestors(ownAddress.getAncestors());
            assetFullInfo.setAddressName(ownAddress.getName());
            assetFullInfo.setAddressFullName(ownAddress.getFullName());
            assetFullInfo.setLongitude(ownAddress.getLongitude());
            assetFullInfo.setLatitude(ownAddress.getLatitude());
        }

        AmsAssetType assetType = amsAssetTypeService.selectAmsAssetTypeByAssetTypeId(assetFullInfoAddVo.getAssetTypeId());
        if (assetType != null) {
            assetFullInfo.setTypeParentId(assetType.getParentId());
            assetFullInfo.setAssetTypeAncestors(assetType.getAncestors());
            assetFullInfo.setAssetTypeName(assetType.getAssetTypeName());
            assetFullInfo.setAssetTypeCode(assetType.getAssetTypeCode());
        }

        AmsAssetProject assetProject = projectService.selectAmsAssetProjectByProjectId(assetFullInfoAddVo.getProjectId());
        if (assetProject != null) {
            assetFullInfo.setProjectName(assetProject.getProjectName());
            assetFullInfo.setProjectDescription(assetProject.getProjectDescription());
        }
        return assetFullInfo;
    }

    @Transactional
    public AmsOwnAddress getOrCreateOwnAddressByNameAndParentIdAndDeptId(AmsOwnAddress address) {

        AmsOwnAddress isExit = amsOwnAddressService.getOne(new QueryWrapper<AmsOwnAddress>().eq(AmsOwnAddress.PARENT_ID, address.getParentId()).eq(AmsOwnAddress.DEPT_ID, address.getDeptId()).eq(AmsOwnAddress.NAME, address.getName()), false);
        if (isExit == null) {
            amsOwnAddressService.save(address);
            isExit = address;
        }
        return isExit;

    }

    //  @D@S("master")
    //@Async
    @Transactional
    public void updateFullInfo(UpdateWrapper<AsmsAssetFullInfo> updateWrapper) {
        //RootContext.bind(xid);
        assetFullInfoService.update(updateWrapper);
        //throw new GlobalException("尝试回滚");
    }

    //  @D@S("master")
    //@Async
    @Transactional
    public void updateFullInfo(AsmsAssetFullInfo assetFullInfo) {
        //RootContext.bind(xid);
        assetFullInfoService.updateById(assetFullInfo);
        //throw new GlobalException("尝试回滚");
    }

    //  @D@S("master")
    //@Async
    @Transactional
    public void saveAssetFullInfo(AsmsAssetFullInfo assetFullInfo) {
        assetFullInfoService.save(assetFullInfo);
        //throw new GlobalException("尝试回滚");
    }

    //  @D@S("master")
    public AsmsAssetFullInfo getAssetFullInfo(QueryWrapper<AsmsAssetFullInfo> queryWrapper) {
        return assetFullInfoService.getOne(queryWrapper, false);
    }

    public List<AmsAssetType> getAssetTypeSummary(List<AssetInfoView> viewList, AmsAssetType assetType) {

        //将所有的资产信息放到map中，提高查询速度
        HashMap<Long, Integer> map = new HashMap<>();

        viewList.forEach(item -> {
            map.merge(item.getAssetTypeId(), 1, (a, b) -> a + b);
        });
        List<AmsAssetType> typeList = amsAssetTypeService.selectAmsAssetTypeList(assetType);
        for (AmsAssetType type : typeList) {
            type.setAssetNum(map.get(type.getAssetTypeId()));
        }
        return amsAssetTypeService.buildTree(typeList);
    }

    /**
     * 获取当前用户能看到的资产数据
     */
    public List<AsmsAssetFullInfo> getUserCanLookAssetInfo(Long startTime, Long endTime) {
        QueryWrapper<AsmsAssetFullInfo> wrapper = new QueryWrapper<>();
        if (startTime != null && endTime != null) {
            wrapper.ge(AsmsAssetFullInfo.CREATE_TIME, startTime).le(AsmsAssetFullInfo.CREATE_TIME, endTime);
        }
        //判断用户的角色
        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
            Set<Long> userOwnDeptIds = tokenService.getUserOwnDeptIds();
            if (userOwnDeptIds.size() > 0) {
                wrapper.in(AsmsAssetFullInfo.OWN_DEPT_ID, userOwnDeptIds);
            } else {
                return new ArrayList<>();
            }
        }
        List<AsmsAssetFullInfo> list = assetFullInfoService.list(wrapper);
        return list;

    }

    /**
     * 在返回分页数据的接口中处理远程调用错误
     * @return 错误信息
     */
    public TableDataInfo resovleError() {
        TableDataInfo info = new TableDataInfo();
        info.setMsg("系统异常，请联系管理员");
        info.setCode(500);
        info.setSuccess(false);
        return info;
    }

    /**
     * 根据当前时间产生SN编号
     * @return
     */
    public String createSn() {
        SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSSS");
        String nowTimeStr = fmt.format(new Date());
        return "AMS" + nowTimeStr;
    }

    /**
     * 获取资产id与资产类型id的Map
     * @return
     */
    public HashMap<Long, Long> getAssetIdTypeIdMap() {
        List<AsmsAssetFullInfo> fullInfos = assetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                .select(AsmsAssetFullInfo.ASSET_ID, AsmsAssetFullInfo.ASSET_TYPE_ID));
        HashMap<Long, Long> assetIdTypeIdMap = new HashMap<>();
        for (AsmsAssetFullInfo fullInfo : fullInfos) {
            if (fullInfo != null) {
                assetIdTypeIdMap.put(fullInfo.getAssetId(), fullInfo.getAssetTypeId());
            }
        }
        return assetIdTypeIdMap;
    }

    /**
     * 获取资产id与资产类型名称的Map
     * @return
     */
    public HashMap<Long, String> getAssetIdTypeNameMap() {
        List<AsmsAssetFullInfo> fullInfos = assetFullInfoService.list(new QueryWrapper<AsmsAssetFullInfo>()
                .select(AsmsAssetFullInfo.ASSET_ID, AsmsAssetFullInfo.ASSET_TYPE_NAME));
        HashMap<Long, String> assetIdTypeNameMap = new HashMap<>();
        for (AsmsAssetFullInfo fullInfo : fullInfos) {
            if (fullInfo != null) {
                assetIdTypeNameMap.put(fullInfo.getAssetId(), fullInfo.getAssetTypeName());
            }
        }
        return assetIdTypeNameMap;
    }

    /**
     * 获取去年的开始时间，如2021-01-01 00:00:00
     * @return 去年第一天凌晨0点的时间戳（ms）
     */
    public Long getLastYearStartTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.YEAR, -1);
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTimeInMillis();
    }

    /**
     * 获取今年的开始时间，如2022-01-01 00:00:00
     * @return 今年第一天凌晨0点的时间戳（ms）
     */
    public Long getThisYearStartTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.DAY_OF_YEAR, 1);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTimeInMillis();
    }

}
